package cn.itcast.account.service.impl;

import cn.itcast.account.entity.AccountFreeze;
import cn.itcast.account.mapper.AccountFreezeMapper;
import cn.itcast.account.mapper.AccountMapper;
import cn.itcast.account.service.TCCService;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static cn.itcast.account.entity.AccountFreeze.State.*;


@Service
public class TCCServiceImpl implements TCCService {
    @Autowired
    private AccountFreezeMapper freezeMapper;
    @Autowired
    private AccountMapper accountMapper;

    @Override
    public void tryDeduct(String userId, int money) {
        String xid = RootContext.getXID();
        AccountFreeze freeze = freezeMapper.selectById(xid);
        if (freeze != null) {
            return;
        }
        accountMapper.deduct(userId, money);
        AccountFreeze accountFreeze = new AccountFreeze();
        accountFreeze.setXid(xid);
        accountFreeze.setUserId(userId);
        accountFreeze.setFreezeMoney(money);
        accountFreeze.setState(TRY);
        freezeMapper.insert(accountFreeze);
    }

    @Override
    public boolean confirm(BusinessActionContext context) {
        String xid = context.getXid();
        int i = freezeMapper.deleteById(xid);
        return i == 1;
    }

    @Override
    public boolean cancel(BusinessActionContext context) {
        String xid = context.getXid();
        AccountFreeze accountFreeze = freezeMapper.selectById(xid);
        if (accountFreeze == null) {
            AccountFreeze freeze = new AccountFreeze();
            freeze.setState(CANCEL);
            freeze.setXid(xid);
            freeze.setUserId(context.getActionContext("userId").toString());
            freeze.setFreezeMoney(0);
            freezeMapper.insert(freeze);
            return true;
        }
        if (accountFreeze.getState() == CANCEL) {
            return true;
        }
        accountMapper.refund(accountFreeze.getUserId(), accountFreeze.getFreezeMoney());
        accountFreeze.setState(CANCEL);
        accountFreeze.setFreezeMoney(0);
        int i = freezeMapper.updateById(accountFreeze);
        return i == 1;
    }
}
